﻿// -----------------------------------------------------------------------
// <copyright file="CourseDetailsService.cs" company="AGR">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace AGR.Services.Course.Contract
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using AGR.Model;
    using AGR.Data.Repository;
    using AGR.Data.Repository.Contract;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class CourseDetailsService : ICourseDetailsService
    {
        private ContextHelper _contextHelper;
        private IRepository<FactCourseSubjectTrainer> _factCourseSubjectTrainerRepository;

        public CourseDetailsService()
        {
            _contextHelper = ContextHelper.GetInstance();
            _factCourseSubjectTrainerRepository = new FactCourseSubjectTrainerRepository(_contextHelper);
        }

        #region Private Methods

        private static void ActionResultError(ActionResult actionResult, Exception ex)
        {
            actionResult.Exception = ex;
            actionResult.IsSystemFailure = true;
            actionResult.Success = false;
        }

        #endregion

        public FactCourseSubjectTrainer GetCourseSubject(string courseCode, string subjectCode)
        {
            if (string.IsNullOrEmpty(courseCode))
                throw new ArgumentNullException(courseCode);
            if (string.IsNullOrEmpty(subjectCode))
                throw new ArgumentNullException(subjectCode);

            return _factCourseSubjectTrainerRepository.FindSingleBy(x => x.CourseCode == courseCode && x.SubjectCode == subjectCode);
        }

        public FactCourseSubjectTrainer GetCourseSubject(Expression<Func<FactCourseSubjectTrainer, bool>> predicate)
        {
            if (predicate == null)
                throw new ArgumentNullException(predicate.ToString());

            return _factCourseSubjectTrainerRepository.FindSingleBy(predicate);
        }

        public IList<FactCourseSubjectTrainer> GetAllCourseSubjects(string courseCode)
        {
            if (string.IsNullOrEmpty(courseCode))
                throw new ArgumentNullException(courseCode);

            return _factCourseSubjectTrainerRepository.FindBy(x => x.CourseCode == courseCode).ToList();
        }

        public IList<FactCourseSubjectTrainer> GetAllCourseSubjects(Expression<Func<FactCourseSubjectTrainer, bool>> predicate)
        {
            if (predicate == null)
                throw new ArgumentNullException(predicate.ToString());

            return _factCourseSubjectTrainerRepository.FindBy(predicate).ToList();
        }

        public ActionResult AddCourseSubject(FactCourseSubjectTrainer entity)
        {
            if (entity == null)
                throw new ArgumentNullException(entity.CourseCode);
            if (string.IsNullOrEmpty(entity.CourseCode) || string.IsNullOrEmpty(entity.SubjectCode))
                throw new ArgumentNullException(entity.CourseCode);
            if (string.IsNullOrEmpty(entity.UserCreated))
                throw new ArgumentNullException(entity.UserCreated);

            ActionResult actionResult = new ActionResult();

            try
            {
                _factCourseSubjectTrainerRepository.Add(entity);
                _factCourseSubjectTrainerRepository.SaveChanges();
                actionResult.Success = true;
                actionResult.Message = actionResult.RecordInserted;
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericAddErrorMessage;
            }

            return actionResult;
        }

        public ActionResult AddCourseSubject(string courseCode, string subjectCode, string employeeCode, string userCreated)
        {
            if (string.IsNullOrEmpty(employeeCode))
                throw new ArgumentNullException(employeeCode);
            if (string.IsNullOrEmpty(courseCode))
                throw new ArgumentNullException(courseCode);
            if (string.IsNullOrEmpty(subjectCode))
                throw new ArgumentNullException(subjectCode);
            if (string.IsNullOrEmpty(userCreated))
                throw new ArgumentNullException(userCreated);

            ActionResult actionResult = new ActionResult();

            try
            {
                var entity = new FactCourseSubjectTrainer()
                {
                    CourseCode = courseCode,
                    SubjectCode = subjectCode,
                    EmployeeCode = employeeCode,
                    UserCreated = userCreated
                };

                _factCourseSubjectTrainerRepository.Add(entity);
                _factCourseSubjectTrainerRepository.SaveChanges();
                actionResult.Success = true;
                actionResult.Message = actionResult.RecordInserted;
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericAddErrorMessage;
            }

            return actionResult;
        }

        public ActionResult UpdateCourseSubject(FactCourseSubjectTrainer entity)
        {
            if (entity == null)
                throw new ArgumentNullException(entity.CourseCode);
            if (string.IsNullOrEmpty(entity.CourseCode) || string.IsNullOrEmpty(entity.SubjectCode))
                throw new ArgumentNullException(entity.CourseCode);
            if (string.IsNullOrEmpty(entity.UserModified))
                throw new ArgumentNullException(entity.UserModified);

            ActionResult actionResult = new ActionResult();

            try
            {
                _factCourseSubjectTrainerRepository.Update(entity);
                _factCourseSubjectTrainerRepository.SaveChanges();
                actionResult.Success = true;
                actionResult.Message = actionResult.RecordUpdated;
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericUpdateErrorMessage;
            }

            return actionResult;
        }

        public ActionResult UpdateCourseSubject(string courseCode, string subjectCode, string employeeCode, string userModified)
        {
            if (string.IsNullOrEmpty(employeeCode))
                throw new ArgumentNullException(employeeCode);
            if (string.IsNullOrEmpty(courseCode))
                throw new ArgumentNullException(courseCode);
            if (string.IsNullOrEmpty(subjectCode))
                throw new ArgumentNullException(subjectCode);
            if (string.IsNullOrEmpty(subjectCode))
                throw new ArgumentNullException(userModified);

            ActionResult actionResult = new ActionResult();

            try
            {
                var entity = _factCourseSubjectTrainerRepository.FindSingleBy(x => x.CourseCode == courseCode &&
                                                                                   x.SubjectCode == subjectCode);

                entity.EmployeeCode = employeeCode;
                entity.UserModified = userModified;

                _factCourseSubjectTrainerRepository.Update(entity);
                _factCourseSubjectTrainerRepository.SaveChanges();
                actionResult.Success = true;
                actionResult.Message = actionResult.RecordUpdated;
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericUpdateErrorMessage;
            }

            return actionResult;
        }

        public ActionResult DeleteCourseSubject(string courseCode, string subjectCode)
        {
            if (string.IsNullOrEmpty(courseCode))
                throw new ArgumentNullException(courseCode);
            if (string.IsNullOrEmpty(subjectCode))
                throw new ArgumentNullException(subjectCode);

            ActionResult actionResult = new ActionResult();

            try
            {
                _factCourseSubjectTrainerRepository.DeleteBy(x => x.CourseCode == courseCode);
                _factCourseSubjectTrainerRepository.SaveChanges();
                actionResult.Success = true;
                actionResult.Message = actionResult.RecordDeleted;
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage;
            }

            return actionResult;
        }

        public ActionResult DeleteCourseSubject(Expression<Func<FactCourseSubjectTrainer, bool>> predicate)
        {
            if (predicate == null)
                throw new ArgumentNullException(predicate.ToString());

            ActionResult actionResult = new ActionResult();

            try
            {
                _factCourseSubjectTrainerRepository.DeleteBy(predicate);
                _factCourseSubjectTrainerRepository.SaveChanges();
                actionResult.Success = true;
                actionResult.Message = actionResult.RecordDeleted;
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage;
            }

            return actionResult;
        }
    }
}
